unit principal;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
  TForPrincipal = class(TForm)

    procedure FormShow(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);

    function Calcular: boolean;
    function NumeroItens: integer;
    function rS(campo: string): string;
    function rN(campo: string): currency;
    function rT(campo: string): string;
    function localizarCampo(campo: string): integer;
    function lerCampo(campo: string): string;
    procedure excluirCampo(campo: string);
    procedure wC(campo, Conteudo: string);
    procedure wN2(campo: string; valor: currency);

  private
    { Private declarations }
  public
    { Public declarations }
    PathArquivoPcn: string;
    PathArquivoCfg: string;
  end;

var

  ForPrincipal: TForPrincipal;
  ArquivoPcn: TstringList;

const

  I10qCom_ = 'I10';
  I10vUnCom_ = 'I10a';
  I11vProd_ = 'I11';
  I14qTrib_ = 'I14';
  I14vUnTrib_ = 'I14a';
  I15vFrete_ = 'I15';
  I16vSeg_ = 'I16';
  I17vDEsc_ = 'I17';
  I17vOutro_ = 'I17a';
  N12cstIcms_ = 'N12';
  N13icmsIpi_ = 'N13#';
  N15vBC_ = 'N15';
  N16pIcms_ = 'N16';
  N17vIcms_ = 'N17';
  N18modBCST_ = 'N18';
  N19pMVAST_ = 'N19';
  N21vBCST_ = 'N21';
  N22pIcmsST_ = 'N22';
  N23vIcmsST_ = 'N23';
  O09cstIpi_ = 'O09';
  O10vBC_ = 'O10';
  O11qUnid_ = 'O11';
  O12vUnid_ = '012';
  O13pIpi_ = 'O13';
  O14vIpi_ = 'O14';
  P04vII_ = 'P04';
  Q06vPIS_ = 'Q06';
  S11vCOFINS_ = 'S11';
  W03vBCicms_ = 'W03';
  W04vIcms_ = 'W04';
  W05vBCST_ = 'W05';
  W06vIcmsST_ = 'W06';
  W07vProd_ = 'W07';
  W08vFrete_ = 'W08';
  W09vSeg_ = 'W09';
  W10vDesc_ = 'W10';
  W11vII_ = 'W11';
  W12vIPI_ = 'W12';
  W13vPIS_ = 'W13';
  W14vCOFINS_ = 'W14';
  W15vOutro_ = 'W15';
  W16vNF_ = 'W16';
  W24RetPIS_ = 'W24';
  W25RetCOFINS_ = 'W25';
  W26RetCSLL_ = 'W26';
  W27BCIRRF_ = 'W27';
  W28IRRF_ = 'W28';
  W29BCRetPrev_ = 'W29';
  W30RetPrev_ = 'W30';

implementation

{$R *.DFM}

function SomenteNumerosEponto(const s: string): string;
var
  i: integer;
begin
  result := '';
  for i := 1 to length(s) do
    if pos(s[i], '.,0123456789') > 0 then
      if s[i] = ',' then
        result := result + '.'
      else
        result := result + s[i];
end;

function S2C(s: string): currency;
begin
  s := stringReplace(s, '.', DecimalSeparator, [rfReplaceAll]);
  s := stringReplace(s, ',', DecimalSeparator, [rfReplaceAll]);
  result := strToCurr(s);
end;

function TU(s: string): string;
begin
  result := Trim(uppercase(s));
end;

function porcento(valor, porcentagem: currency): currency;
begin
  result := (valor / 100) * porcentagem;
end;

////////////////////////////////////////////////////////////////////////////////

procedure TForPrincipal.FormCreate(Sender: TObject);
begin
  ArquivoPcn := TStringList.Create;
end;

procedure TForPrincipal.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  ArquivoPcn.Destroy;
end;

procedure TForPrincipal.FormShow(Sender: TObject);
begin
  //if ParamCount = 0 then
  //begin
  //  close;
  //  exit;
  //end;
  //PathArquivoPcn := ParamStr(0);
  //PathArquivoCfg := ParamStr(1);
  PathArquivoPcn := 'c:\testeTXTpcne.txt';
  ArquivoPcn.LoadFromFile(PathArquivoPcn);
  Calcular;
  Close;
end;

//

function TForPrincipal.localizarCampo(campo: string): integer;
var
  i: integer;
begin
  result := -1;
  for i := 0 to arquivoPcn.count - 1 do
    if pos(campo, ArquivoPcn[i]) > 0 then
      result := i;
end;

function TForPrincipal.lerCampo(campo: string): string;
var
  i: integer;
begin
  i := localizarCampo(campo);
  result := copy(ArquivoPcn[i], pos('|', ArquivoPcn[i]) + 1, maxInt);
end;

procedure TForPrincipal.excluirCampo(campo: string);
var
  i: integer;
begin
  i := localizarCampo(campo);
  if localizarCampo(campo) = -1 then
    exit;
  arquivoPcn.Delete(i);
end;

procedure TForPrincipal.wC(Campo, Conteudo: string);
var
  i: integer;
begin
  i := localizarCampo(campo);
  if localizarCampo(campo) = -1 then
  begin
    arquivoPcn.add(campo + conteudo);
    exit;
  end;
  arquivoPcn[i] := campo + conteudo;
end;

//

function TForPrincipal.rS(campo: string): string;
var
  i: integer;
begin
  result := '';
  for i := 0 to ArquivoPcn.count - 1 do
  begin
    if pos(campo, ArquivoPcn[i]) > 0 then
      result := copy(ArquivoPcn[i], pos('|', ArquivoPcn[i]) + 1, maxInt);
  end;
end;

function TForPrincipal.rN(campo: string): currency;
var
  s: string;
begin
  campo := TU(campo) + '|';
  result := 0;
  s := stringReplace(Trim(uppercase(rS(campo))), ',', '.', [rfReplaceAll]);
  if (s = SomenteNumerosEponto(s)) and (s <> '') then
    result := S2C(s);
end;

function TForPrincipal.rT(campo: string): string;
begin
  campo := TU(campo) + '|';
  result := rS(campo) + '-';
  result := trim(copy(result, 1, pos('-', result) - 1));
end;

procedure TForPrincipal.wN2(campo: string; Valor: currency);
var
  s: string;
begin
  campo := TU(campo) + '|';
  s := stringReplace(CurrToStr(Valor), ',', '.', [rfReplaceAll]);
  s := Trim(copy(s, 1, pos('.', s) + 2));
  wC(campo, s);
end;

//

function TForPrincipal.NumeroItens: integer;
var
  i: integer;
begin
  result := 0;
  for i := 0 to ArquivoPcn.count - 1 do
  begin
    if (pos('<', ArquivoPcn[i]) = 1) and (pos('>K=1|', ArquivoPcn[i]) > 0) then
      inc(result);
  end;
end;

function TForPrincipal.Calcular: boolean;
var

  i: integer;
  DSLN: string;

  I11vProd: currency;
  I15vFrete: currency;
  I16vSeg: currency;
  I17vOutro: currency;
  I17vDesc: currency;
  O09cstIpi: string;
  O14vIpi: currency;
  N12cstIcms: string;
  N13icmsIpi: string;
  N15vBC: currency;
  N15vBCsemIpi: currency;
  N19pMVAST: currency;
  N18modBCST: string;
  N21vBCST: currency;
  N23vIcmsST: currency;
  W03vBCicms: currency;
  W04vIcms: currency;
  W05vBCST: currency;
  W06vIcmsST: currency;
  W07vProd: currency;
  W08vFrete: currency;
  W09vSeg: currency;
  W10vDesc: currency;
  W11vII: currency;
  W12vIPI: currency;
  W13vPIS: currency;
  W14vCOFINS: currency;
  W15vOutro: currency;
  W16vNF: currency;
  W24RetPIS: currency;
  W25RetCOFINS: currency;
  W26RetCSLL: currency;
  W27BCIRRF: currency;
  W28IRRF: currency;
  W29BCRetPrev: currency;
  W30RetPrev: currency;

  iItens: integer;

begin

  result := true;

  // ITENS /////////////////////////////////////////////////////////////////////

  for i := 1 to NumeroItens do
  begin

    DSLN := '{1}(' + IntToStr(i) + ')';

    I15vFrete := rN(DSLN + I15vFrete_);
    I16vSeg := rN(DSLN + I16vSeg_);
    I17vOutro := rN(DSLN + I17vOutro_);
    I17vDesc := rN(DSLN + I17vDesc_);
    O09cstIpi := rT(DSLN + O09cstIpi_);
    N12cstIcms := rT(DSLN + N12cstIcms_);
    N13icmsIpi := rT(DSLN + N13icmsIpi_);
    N18modBCST := rT(DSLN + N18modBCST_);

    (* VALOR PRODUTOS *)

    I11vProd := rN(DSLN + I10qCom_) * rN(DSLN + I10vUnCom_);

    wN2(DSLN + I11vProd_, I11vProd);
    wN2(DSLN + I14vUnTrib_, I11vProd / rN(DSLN + I14qTrib_));

    (* IPI *)

    O14vIpi := 0;

    if O09cstIpi = 'A' then
    begin
      wN2(DSLN + O10vBC_, I11vProd);
      O14vIpi := porCento(I11vProd, rN(DSLN + O13pIPI_));
    end;
    if O09cstIpi = 'B' then
    begin
      O14vIpi := rN(DSLN + O11qUnid_) * rN(DSLN + O12vUnid_);
    end;
    wN2(DSLN + O14vIpi_, O14vIpi);

    (* ICMS *)

    N19pMVAST := rN(DSLN + N19pMVAST_);

    if (N12cstIcms = '00') or (N12cstIcms = '10') then
    begin
      N15vBCsemIpi := I11vProd + I15vFrete + I16vSeg + I17vOutro;
      N15vBC := N15vBCsemIpi;
      if N13icmsIpi = '1' then
        N15vBC := N15vBCsemIpi + O14vIpi;
      wN2(DSLN + N15vBC_, N15vBC);
      wN2(DSLN + N17vIcms_, porcento(N15vBC, rN(DSLN + N16pIcms_)));
    end;

    if N12cstIcms = '10' then
    begin
      if N18modBCST = '4' then
      begin
        N21vBCST := N15vBCsemIpi + O14vIpi + porcento((N15vBCsemIpi + O14vIpi), N19pMVAST);
        N23vIcmsST := porcento(N21vBCST, rN(DSLN + N22pIcmsST_)) - rN(DSLN + N17vIcms_);
        wN2(DSLN + N21vBCST_, N21vBCST);
        wN2(DSLN + N23vIcmsST_, N23vIcmsST);
      end;
    end;

  end;

  // TOTAIS ////////////////////////////////////////////////////////////////////

  W03vBCicms := 0;
  W04vIcms := 0;
  W05vBCST := 0;
  W06vIcmsST := 0;
  W07vProd := 0;
  W08vFrete := 0;
  W09vSeg := 0;
  W10vDesc := 0;
  W11vII := 0;
  W12vIPI := 0;
  W13vPIS := 0;
  W14vCOFINS := 0;
  W15vOutro := 0;
  W16vNF := 0;
  W24RetPIS := 0;
  W25RetCOFINS := 0;
  W26RetCSLL := 0;
  W27BCIRRF := 0;
  W28IRRF := 0;
  W29BCRetPrev := 0;
  W30RetPrev := 0;

  for i := 1 to NumeroItens do
  begin

    DSLN := '{1}(' + IntToStr(i) + ')';

    W07vProd := W07vProd + rN(DSLN + I11vProd_);
    W08vFrete := W08vFrete + rN(DSLN + I15vFrete_);
    W09vSeg := W09vSeg + rN(DSLN + I16vSeg_);
    W10vDesc := W10vDesc + rN(DSLN + I17vDesc_);
    W15vOutro := W15vOutro + rN(DSLN + I17vOutro_);

    W03vBCicms := W03vBCicms + rN(DSLN + N15vBC_);
    W04vIcms := W04vIcms + rN(DSLN + N17vIcms_);
    W05vBCST := W05vBCST + rN(DSLN + N21vBCST_);
    W06vIcmsST := W06vIcmsST + rN(DSLN + N23vIcmsST_);

    W12vIPI := W12vIPI + rN(DSLN + O14vIpi_);

    W11vII := W11vII + rN(DSLN + P04vII_);

    W13vPIS := W13vPIS + rN(DSLN + Q06vPIS_);
    //      W24RetPIS := W24RetPIS +

    W14vCOFINS := W14vCOFINS + rN(DSLN + S11vCOFINS_);
    //      W25RetCOFINS := W25RetCOFINS + rN(
  end;

  wN2(W03vBCicms_, W03vBCicms);
  wN2(W04vIcms_, W04vIcms);
  wN2(W05vBCST_, W05vBCST);
  wN2(W06vIcmsST_, W06vIcmsST);
  wN2(W07vProd_, W07vProd);
  wN2(W08vFrete_, W08vFrete);
  wN2(W09vSeg_, W09vSeg);
  wN2(W10vDesc_, W10vDesc);
  wN2(W11vII_, W11vII);
  wN2(W12vIPI_, W12vIPI);
  wN2(W13vPIS_, W13vPIS);
  wN2(W14vCOFINS_, W14vCOFINS);
  wN2(W15vOutro_, W15vOutro);

  W16vNF := W07vProd
    + W06vIcmsST
    + W08vFrete
    + W09vSeg
    + W12vIPI
    + W15vOutro
    - W10vDesc;

  wN2(W16vNF_, W16vNF);

  wN2(W24RetPIS_, W24RetPIS);
  wN2(W25RetCOFINS_, W25RetCOFINS);
  wN2(W26RetCSLL_, W26RetCSLL);
  wN2(W27BCIRRF_, W27BCIRRF);
  wN2(W28IRRF_, W28IRRF);
  wN2(W29BCRetPrev_, W29BCRetPrev);
  wN2(W30RetPrev_, W30RetPrev);

end;

end.

